1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.apache.tapestry5.internal.services;
16
17 import java.lang.reflect.Method;
18 import java.util.Collections;
19 import java.util.Date;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.tapestry5.Block;
24 import org.apache.tapestry5.PropertyConduit;
25 import org.apache.tapestry5.PropertyConduit2;
26 import org.apache.tapestry5.beaneditor.NonVisual;
27 import org.apache.tapestry5.beaneditor.Validate;
28 import org.apache.tapestry5.integration.app1.data.IntegerHolder;
29 import org.apache.tapestry5.internal.InternalPropertyConduit;
30 import org.apache.tapestry5.internal.bindings.PropBindingFactoryTest;
31 import org.apache.tapestry5.internal.test.InternalBaseTestCase;
32 import org.apache.tapestry5.internal.util.Holder;
33 import org.apache.tapestry5.internal.util.IntegerRange;
34 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
35 import org.apache.tapestry5.services.PropertyConduitSource;
36 import org.testng.annotations.AfterClass;
37 import org.testng.annotations.BeforeClass;
38 import org.testng.annotations.Test;
39
40
41
42
43
44 public class PropertyConduitSourceImplTest extends InternalBaseTestCase
45 {
46 private PropertyConduitSource source;
47
48 @BeforeClass
49 public void setup()
50 {
51 source = getObject(PropertyConduitSource.class, null);
52 }
53
54 @AfterClass
55 public void cleanup()
56 {
57 source = null;
58 }
59
60 @Test
61 public void literal_conduits_have_invariant_annotation()
62 {
63 PropertyConduit pc = source.create(CompositeBean.class, "12345");
64
65 Invariant annotation = pc.getAnnotation(Invariant.class);
66
67 assertNotNull(annotation);
68
69 assertSame(annotation.annotationType(), Invariant.class);
70 }
71
72 @Test
73 public void range_variable_to()
74 {
75 PropertyConduit pc = source.create(IntegerHolder.class, "10..value");
76 IntegerHolder h = new IntegerHolder();
77
78 h.setValue(5);
79
80 IntegerRange ir = (IntegerRange) pc.get(h);
81
82 assertEquals(ir, new IntegerRange(10, 5));
83 }
84
85 @Test
86 public void range_variable_from()
87 {
88 PropertyConduit pc = source.create(IntegerHolder.class, "value..99");
89 IntegerHolder h = new IntegerHolder();
90
91 h.setValue(72);
92
93 IntegerRange ir = (IntegerRange) pc.get(h);
94
95 assertEquals(ir, new IntegerRange(72, 99));
96 }
97
98 @Test
99 public void literal_conduits_are_not_updateable()
100 {
101 PropertyConduit pc = source.create(CompositeBean.class, "12345");
102 CompositeBean bean = new CompositeBean();
103
104 try
105 {
106 pc.set(bean, 42);
107 unreachable();
108 } catch (RuntimeException ex)
109 {
110 assertEquals(ex.getMessage(), "Literal values are not updateable.");
111 }
112 }
113
114 @Test
115 public void this_literal_conduit_is_not_updateable()
116 {
117 PropertyConduit normal = source.create(CompositeBean.class, "this");
118 CompositeBean bean = new CompositeBean();
119
120 try
121 {
122 normal.set(bean, 42);
123 unreachable();
124 } catch (RuntimeException ex)
125 {
126 assertEquals(ex.getMessage(), "Literal values are not updateable.");
127 }
128 }
129
130 @Test
131 public void question_dot_operator_for_object_type()
132 {
133 InternalPropertyConduit normal = (InternalPropertyConduit) source.create(CompositeBean.class,
134 "simple.firstName");
135 InternalPropertyConduit smart = (InternalPropertyConduit) source.create(CompositeBean.class,
136 "simple?.firstName");
137
138 CompositeBean bean = new CompositeBean();
139 bean.setSimple(null);
140
141 assertEquals(normal.getPropertyName(), "firstName");
142 assertEquals(smart.getPropertyName(), "firstName");
143
144 try
145 {
146 normal.get(bean);
147 unreachable();
148 } catch (NullPointerException ex)
149 {
150
151 }
152
153 assertNull(smart.get(bean));
154
155 try
156 {
157 normal.set(bean, "Howard");
158 unreachable();
159 } catch (NullPointerException ex)
160 {
161
162 }
163
164
165
166 smart.set(bean, "Howard");
167 }
168
169 static class GenericBean {
170 public List<Date> dates;
171 public List<GenericBean> genericBeans;
172
173 public List<Long> getLongs() {
174 return Collections.emptyList();
175 }
176
177 public void setMap(Map<String, Integer> map) {
178 }
179 }
180
181 @Test
182 public void generic_types_are_determined()
183 {
184 PropertyConduit2 datesConduit = (PropertyConduit2) source.create(GenericBean.class, "dates");
185 PropertyConduit2 longsConduit = (PropertyConduit2) source.create(GenericBean.class, "longs");
186 PropertyConduit2 nestedDatesConduit = (PropertyConduit2) source.create(GenericBean.class, "genericBeans.get(0).dates");
187 PropertyConduit2 mapConduit = (PropertyConduit2) source.create(GenericBean.class, "map");
188 assertEquals(datesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");
189 assertEquals(longsConduit.getPropertyGenericType().toString(), "java.util.List<java.lang.Long>");
190 assertEquals(nestedDatesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");
191 assertEquals(mapConduit.getPropertyGenericType().toString(), "java.util.Map<java.lang.String, java.lang.Integer>");
192 }
193
194 @Test
195 public void method_names_are_matched_caselessly()
196 {
197 InternalPropertyConduit conduit = (InternalPropertyConduit) source.create(CompositeBean.class,
198 "GETSIMPLE().firstName");
199
200 assertEquals(conduit.getPropertyName(), "firstName");
201
202 CompositeBean bean = new CompositeBean();
203 SimpleBean inner = new SimpleBean();
204 bean.setSimple(inner);
205
206 conduit.set(bean, "Howard");
207
208 assertEquals(inner.getFirstName(), "Howard");
209 }
210
211 @Test
212 public void generics()
213 {
214 String string = "surprise";
215 StringHolder stringHolder = new StringHolder();
216 stringHolder.put(string);
217 StringHolderBean bean = new StringHolderBean();
218 bean.setValue(stringHolder);
219
220 PropertyConduit conduit = source.create(StringHolderBean.class, "value.get()");
221
222 assertSame(conduit.get(bean), string);
223
224 assertSame(conduit.getPropertyType(), String.class);
225 }
226
227 public static class One<A, B>
228 {
229 A a;
230 B b;
231
232 public A getA()
233 {
234 return a;
235 }
236
237 public void setA(A a)
238 {
239 this.a = a;
240 }
241
242 public B getB()
243 {
244 return b;
245 }
246
247 public void setB(B b)
248 {
249 this.b = b;
250 }
251 }
252
253 public static class Two<B> extends One<String, B>
254 {
255 String s;
256 B b2;
257
258 public String getS()
259 {
260 return s;
261 }
262
263 public void setS(String s)
264 {
265 this.s = s;
266 }
267
268 public B getB2()
269 {
270 return b2;
271 }
272
273 public void setB2(B b2)
274 {
275 this.b2 = b2;
276 }
277 }
278
279 public static class Three extends Two<Long>
280 {
281 Long x;
282
283 public Long getX()
284 {
285 return x;
286 }
287
288 public void setX(Long x)
289 {
290 this.x = x;
291 }
292 }
293
294 public static class WithParameters<C, T>
295 {
296 private C type1Property;
297 public C type1Field;
298 private T type2Property;
299 public T type2Field;
300
301 private T[] type2ArrayProperty;
302 public T[] type2ArrayField;
303
304 public C getType1Property()
305 {
306 return type1Property;
307 }
308
309 public void setType1Property(C type1Property)
310 {
311 this.type1Property = type1Property;
312 }
313
314 public T getType2Property()
315 {
316 return type2Property;
317 }
318
319 public void setType2Property(T type2Property)
320 {
321 this.type2Property = type2Property;
322 }
323
324 public T[] getType2ArrayProperty()
325 {
326 return type2ArrayProperty;
327 }
328
329 public void setType2ArrayProperty(T[] type2ArrayProperty)
330 {
331 this.type2ArrayProperty = type2ArrayProperty;
332 }
333 }
334
335 public static class RealizedParameters extends WithParameters<Holder<SimpleBean>, Long>
336 {
337 }
338
339 public static class WithGenericProperties
340 {
341 public Holder<SimpleBean> holder = new Holder<SimpleBean>();
342 }
343
344 public static interface GenericInterface<A, B>
345 {
346 A genericA();
347
348 B genericB();
349 }
350
351 public static class WithRealizedGenericInterface implements GenericInterface<String, Long>
352 {
353 String a;
354 Long b;
355
356 public String genericA()
357 {
358 return a;
359 }
360
361 public Long genericB()
362 {
363 return b;
364 }
365 }
366
367 @Test
368 public void generic_properties()
369 {
370 final WithGenericProperties bean = new WithGenericProperties();
371 final String first = "John";
372 final String last = "Doe";
373 final SimpleBean simple = new SimpleBean();
374 simple.setLastName(last);
375 simple.setAge(2);
376 simple.setFirstName(first);
377 bean.holder.put(simple);
378
379 PropertyConduit conduit = source.create(WithGenericProperties.class, "holder.get().firstName");
380 assertSame(conduit.get(bean), first);
381 }
382
383 @Test
384 public void generic_parameterized_base_with_properties()
385 {
386 final String first = "John";
387 final String last = "Doe";
388 final SimpleBean simple = new SimpleBean();
389 simple.setAge(2);
390 simple.setFirstName(first);
391 simple.setLastName(last);
392
393 final RealizedParameters bean = new RealizedParameters();
394 final Holder<SimpleBean> holder = new Holder<SimpleBean>();
395 holder.put(simple);
396 bean.setType1Property(holder);
397 bean.setType2Property(1234L);
398 bean.type1Field = holder;
399 bean.type2Field = 5678L;
400 bean.type2ArrayField = new Long[]
401 {123L, 456L};
402
403 PropertyConduit conduit = source.create(RealizedParameters.class, "type1property.get().firstName");
404 assertSame(conduit.get(bean), first);
405 conduit.set(bean, "Change");
406 assertSame(conduit.get(bean), "Change");
407 conduit.set(bean, first);
408
409 conduit = source.create(RealizedParameters.class, "type1field.get().firstName");
410 assertSame(conduit.get(bean), first);
411
412 conduit = source.create(RealizedParameters.class, "type2field");
413 assertEquals(conduit.get(bean), bean.type2Field);
414
415 conduit = source.create(RealizedParameters.class, "type2property");
416 assertEquals(conduit.get(bean), bean.getType2Property());
417
418 conduit = source.create(RealizedParameters.class, "type2ArrayField");
419 assertEquals(conduit.get(bean), bean.type2ArrayField);
420
421 }
422
423 @Test
424 public void generic_interface()
425 {
426 final WithRealizedGenericInterface bean = new WithRealizedGenericInterface();
427 bean.a = "Hello";
428 bean.b = 12345L;
429
430 PropertyConduit conduit = source.create(WithRealizedGenericInterface.class, "genericA()");
431 assertSame(conduit.get(bean), "Hello");
432 conduit = source.create(WithRealizedGenericInterface.class, "genericB()");
433 assertEquals(conduit.get(bean), 12345L);
434 }
435
436 @Test
437 public void generic_nested()
438 {
439 Three bean = new Three();
440 bean.setA("hello");
441 bean.setB(123L);
442 bean.setB2(1235L);
443 bean.setX(54321L);
444
445 PropertyConduit conduit = source.create(Three.class, "a");
446 assertSame(conduit.get(bean), "hello");
447 }
448
449 @Test
450 public void null_root_object()
451 {
452 PropertyConduit conduit = source.create(StringHolderBean.class, "value.get()");
453
454 try
455 {
456 conduit.get(null);
457 unreachable();
458 } catch (NullPointerException ex)
459 {
460 assertEquals(ex.getMessage(), "Root object of property expression 'value.get()' is null.");
461 }
462 }
463
464 @Test
465 public void null_property_in_chain()
466 {
467 PropertyConduit conduit = source.create(CompositeBean.class, "simple.lastName");
468
469 CompositeBean bean = new CompositeBean();
470 bean.setSimple(null);
471
472 try
473 {
474 conduit.get(bean);
475 unreachable();
476 } catch (NullPointerException ex)
477 {
478 assertMessageContains(ex, "Property 'simple' (within property expression 'simple.lastName', of",
479 ") is null.");
480 }
481 }
482
483 @Test
484 public void last_term_may_be_null()
485 {
486 PropertyConduit conduit = source.create(CompositeBean.class, "simple.firstName");
487
488 CompositeBean bean = new CompositeBean();
489
490 bean.getSimple().setFirstName(null);
491
492 assertNull(conduit.get(bean));
493 }
494
495 @Test
496 public void field_annotations_are_visible()
497 {
498 PropertyConduit conduit = source.create(CompositeBean.class, "simple.firstName");
499
500 Validate annotation = conduit.getAnnotation(Validate.class);
501
502 assertNotNull(annotation);
503
504 assertEquals(annotation.value(), "required");
505 }
506
507 @Test
508 public void method_invocation_with_integer_arguments()
509 {
510 PropertyConduit conduit = source.create(EchoBean.class, "echoInt(storedInt, 3)");
511 EchoBean bean = new EchoBean();
512
513 for (int i = 0; i < 10; i++)
514 {
515 bean.setStoredInt(i);
516 assertEquals(conduit.get(bean), new Integer(i * 3));
517 }
518 }
519
520 @Test
521 public void method_invocation_with_double_argument()
522 {
523 PropertyConduit conduit = source.create(EchoBean.class, "echoDouble(storedDouble, 2.0)");
524 EchoBean bean = new EchoBean();
525
526 double value = 22. / 7.;
527
528 bean.setStoredDouble(value);
529
530 assertEquals(conduit.get(bean), new Double(2. * value));
531 }
532
533 @Test
534 public void method_invocation_with_string_argument()
535 {
536 PropertyConduit conduit = source.create(EchoBean.class, "echoString(storedString, 'B4', 'AFTER')");
537 EchoBean bean = new EchoBean();
538
539 bean.setStoredString("Moe");
540
541 assertEquals(conduit.get(bean), "B4 - Moe - AFTER");
542 }
543
544 @Test
545 public void method_invocation_using_dereference()
546 {
547 PropertyConduit conduit = source.create(EchoBean.class, "echoString(storedString, stringSource.value, 'beta')");
548 EchoBean bean = new EchoBean();
549
550 StringSource source = new StringSource("alpha");
551
552 bean.setStringSource(source);
553 bean.setStoredString("Barney");
554
555 assertEquals(conduit.get(bean), "alpha - Barney - beta");
556 }
557
558 @Test
559 public void top_level_list()
560 {
561 PropertyConduit conduit = source.create(EchoBean.class, "[ 1, 2.0, storedString ]");
562 EchoBean bean = new EchoBean();
563
564 bean.setStoredString("Lisa");
565
566 List l = (List) conduit.get(bean);
567
568 assertListsEquals(l, new Long(1), new Double(2.0), "Lisa");
569 }
570
571 @Test
572 public void empty_list()
573 {
574 PropertyConduit conduit = source.create(EchoBean.class, "[ ]");
575 EchoBean bean = new EchoBean();
576
577 bean.setStoredString("Lisa");
578
579 List l = (List) conduit.get(bean);
580
581 assertEquals(l.size(), 0);
582 }
583
584 @Test
585 public void list_as_method_argument()
586 {
587 PropertyConduit conduit = source.create(EchoBean.class, "echoList([ 1, 2.0, storedString ])");
588 EchoBean bean = new EchoBean();
589
590 bean.setStoredString("Bart");
591
592 List l = (List) conduit.get(bean);
593
594 assertListsEquals(l, new Long(1), new Double(2.0), "Bart");
595 }
596
597 @Test
598 public void arrays_as_method_argument()
599 {
600 PropertyConduit conduit = source.create(EchoBean.class, "echoArray(storedArray)");
601 EchoBean bean = new EchoBean();
602
603 bean.setStoredArray(new Number[][]
604 {new Integer[]
605 {1, 2}, new Double[]
606 {3.0, 4.0}});
607
608 Number[][] array = (Number[][]) conduit.get(bean);
609
610 assertArraysEqual(array[0], 1, 2);
611 assertArraysEqual(array[1], 3.0, 4.0);
612 }
613
614 @Test
615 public void top_level_map()
616 {
617 PropertyConduit conduit = source.create(EchoBean.class, "{'one': true, 'two': 2.0, stringSource.value: 3, 'four': storedString}");
618 EchoBean bean = new EchoBean();
619
620 bean.setStoredString("four");
621 bean.setStringSource(new StringSource("three"));
622
623 Map actual = (Map) conduit.get(bean);
624 assertEquals(actual.get("one"), true);
625 assertEquals(actual.get("two"), 2.0);
626 assertEquals(actual.get("three"), 3L);
627 assertEquals(actual.get("four"), "four");
628 }
629
630 @Test
631 public void empty_map()
632 {
633 PropertyConduit conduit = source.create(EchoBean.class, "{ }");
634 EchoBean bean = new EchoBean();
635 Map m = (Map) conduit.get(bean);
636
637 assertTrue(m.isEmpty());
638
639 }
640
641 @Test
642 public void map_as_method_argument()
643 {
644 PropertyConduit conduit = source.create(EchoBean.class, "echoMap({ 1: 'one', 2.0: 'two', storedString: stringSource.value })");
645 EchoBean bean = new EchoBean();
646
647 bean.setStoredString("3");
648 bean.setStringSource(new StringSource("three"));
649
650 Map m = (Map) conduit.get(bean);
651 assertEquals("one", m.get(1L));
652 assertEquals("two", m.get(2.0));
653 assertEquals("three", m.get("3"));
654
655 }
656
657 @Test
658 public void not_operator()
659 {
660 PropertyConduit conduit = source.create(IntegerHolder.class, "! value");
661 IntegerHolder holder = new IntegerHolder();
662
663 assertEquals(conduit.get(holder), Boolean.TRUE);
664
665 holder.setValue(99);
666
667 assertEquals(conduit.get(holder), Boolean.FALSE);
668 }
669
670 @Test
671 public void not_operator_in_subexpression()
672 {
673 PropertyConduit conduit = source.create(Switch.class, "label(! value)");
674
675 Switch sw = new Switch();
676
677 assertEquals(conduit.get(sw), "aye");
678
679 sw.setValue(true);
680
681 assertEquals(conduit.get(sw), "nay");
682 }
683
684
685
686
687 @Test
688 public void object_methods_can_be_invoked()
689 {
690 PropertyConduit conduit = source.create(Block.class, "toString()");
691
692 Block b = new Block()
693 {
694 @Override
695 public String toString()
696 {
697 return "Do You Grok Ze Block?";
698 }
699 };
700
701 assertEquals(conduit.get(b), "Do You Grok Ze Block?");
702 }
703
704 @Test
705 public void parse_error_in_property_expression()
706 {
707 try
708 {
709 source.create(IntegerHolder.class, "getValue(");
710 unreachable();
711 } catch (RuntimeException ex)
712 {
713
714
715 assertEquals(ex.getMessage(),
716 "Error parsing property expression 'getValue(': line 1:8 no viable alternative at input '('.");
717 }
718 }
719
720 @Test
721 public void lexer_error_in_property_expression()
722 {
723 try
724 {
725 source.create(IntegerHolder.class, "fred #");
726 unreachable();
727 } catch (RuntimeException ex)
728 {
729 assertEquals(ex.getMessage(),
730 "Error parsing property expression 'fred #': Unable to parse input at character position 6.");
731 }
732 }
733
734 @Test
735 public void boolean_constant_as_method_parameter()
736 {
737 Bedrock bedrock = new Bedrock();
738
739 PropertyConduit trueConduit = source.create(Bedrock.class, "toName(true)");
740 PropertyConduit falseConduit = source.create(Bedrock.class, "toName(false)");
741
742 assertEquals(trueConduit.get(bedrock), "Fred");
743 assertEquals(falseConduit.get(bedrock), "Barney");
744 }
745
746
747
748
749 @Test
750 public void dereference_result_of_method_invocation()
751 {
752 ComplexObject co = new ComplexObject();
753 PropertyConduit pc = source.create(ComplexObject.class, "get(nestedIndex).name");
754
755 assertEquals(pc.get(co), "zero");
756
757 co.setNestedIndex(1);
758
759 assertEquals(pc.get(co), "one");
760 }
761
762 @Test
763 public void public_object_field()
764 {
765 PublicFieldBean bean = new PublicFieldBean();
766
767 bean.stringField = "x";
768
769 PropertyConduit pc = source.create(PublicFieldBean.class, "stringField");
770
771 assertEquals(pc.get(bean), "x");
772
773 pc.set(bean, "y");
774
775 assertEquals(bean.stringField, "y");
776 }
777
778 @Test
779 public void navigate_through_public_field()
780 {
781 PublicFieldBean bean = new PublicFieldBean();
782 PublicFieldBeanHolder holder = new PublicFieldBeanHolder(bean);
783
784 bean.stringField = "x";
785
786 PropertyConduit pc = source.create(PublicFieldBeanHolder.class, "bean.stringField");
787
788 assertEquals(pc.get(holder), "x");
789
790 pc.set(holder, "y");
791
792 assertEquals(bean.stringField, "y");
793 }
794
795 @Test
796 public void public_primitive_field()
797 {
798 PublicFieldBean bean = new PublicFieldBean();
799
800 bean.intField = 99;
801
802
803
804 PropertyConduit pc = source.create(PublicFieldBean.class, "IntField");
805
806 assertEquals(pc.get(bean), new Integer(99));
807
808 pc.set(bean, 37);
809
810 assertEquals(bean.intField, 37);
811 }
812
813 @Test
814 public void annotation_of_public_field()
815 {
816 PropertyConduit pc = source.create(PublicFieldBean.class, "StringField");
817
818 assertNotNull(pc.getAnnotation(NonVisual.class));
819 }
820
821
822
823
824 @Test
825 public void this_and_null_inside_array()
826 {
827 PropertyConduit pc = source.create(NonVisualBean.class, "[this, null]");
828
829 Object bean = new NonVisualBean();
830
831 List list = (List) pc.get(bean);
832
833 assertEquals(list.size(), 2);
834 assertSame(list.get(0), bean);
835 assertNull(list.get(1));
836 }
837
838
839
840
841 @Test
842 public void public_static_fields_are_accessible()
843 {
844 PropertyConduit pc = source.create(PublicStaticFieldBean.class, "value");
845
846 assertSame(pc.get(null), PublicStaticFieldBean.VALUE);
847
848 pc.set(null, "new-value");
849
850 assertEquals(PublicStaticFieldBean.VALUE, "new-value");
851 }
852
853 @Test
854 public void final_static_fields_are_read_only()
855 {
856 PropertyConduit pc = source.create(PublicStaticFieldBean.class, "read_only");
857
858 try
859 {
860 pc.set(null, "new-value");
861 unreachable();
862 } catch (RuntimeException ex)
863 {
864 assertEquals(ex.getMessage(),
865 "Expression 'read_only' for class org.apache.tapestry5.internal.services.PublicStaticFieldBean is read-only.");
866 }
867 }
868
869 @Test
870 public void public_static_field_in_an_array()
871 {
872 PropertyConduit pc = source.create(PublicStaticFieldBean.class, "[read_only]");
873
874
875
876 List<String> actual = (List<String>) pc.get(new PublicStaticFieldBean());
877
878 assertListsEquals(actual, PublicStaticFieldBean.READ_ONLY);
879 }
880
881
882 @Test
883 public void covariant_property_return_type() {
884
885
886 try {
887 assertConduitPropertyType(Foo.class, "bar", Bar.class);
888 } catch (AssertionError e) {
889 List<Method> matches = CollectionFactory.newList();
890 for (Method method : Foo.class.getMethods()) {
891 if (method.getName().equals("getBar")) {
892 matches.add(method);
893 }
894 }
895 fail(String.format("%s (possible candidates %s)", e.getMessage(), matches));
896 }
897 assertConduitPropertyType(AbstractFoo.class, "bar", AbstractBar.class);
898
899
900 assertConduitPropertyType(RobertMyClass.class, "foo.robertBarValue", int.class);
901
902 }
903
904
905 public static abstract class AbstractBar
906 {
907 }
908
909 public static class Bar extends AbstractBar
910 {
911 }
912
913 public static abstract class AbstractFoo
914 {
915 public abstract AbstractBar getBar();
916 }
917
918 public static class Foo extends AbstractFoo
919 {
920 Bar bar;
921
922 public Bar getBar()
923 {
924 return bar;
925 }
926 }
927
928 public static interface RobertFoo
929 {
930 int getRobertFooValue();
931 }
932
933 public static interface RobertBar extends RobertFoo
934 {
935 int getRobertBarValue();
936 }
937
938 public static interface RobertBaz
939 {
940 RobertFoo getFoo();
941 }
942
943 public static interface RobertQux extends RobertBaz
944 {
945 RobertBar getFoo();
946 }
947
948 public static class RobertAbstractClass implements RobertBaz
949 {
950 public RobertFoo getFoo()
951 {
952 return null;
953 }
954 }
955
956 public static class RobertMyClass extends RobertAbstractClass implements RobertQux
957 {
958 public RobertBar getFoo()
959 {
960 return null;
961 }
962 }
963
964 private void assertConduitPropertyType(Class<?> origin, String property, Class<?> expectedType) {
965 assertEquals(expectedType, source.create(origin, property).getPropertyType());
966 }
967 }